<script lang="ts" setup>
import { ref, reactive, onMounted, computed, h } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Modal, message } from 'ant-design-vue'
import FooterToolbar from '@/layouts/basic/FooterToolbar.vue'
import AddCover from '@/components/AddCover.vue'
import AddVideo from '@/components/AddVideo.vue'
import MaterialTypeSelectModal from '@/components/MaterialTypeSelectModal.vue'
import RichTextEditor from '@/components/RichTextEditor.vue'
import type { TableColumns } from '@/types/antd'
import { t } from '@/libs/utils/i18n'
import Enums from '@/datas/Enums'

defineOptions({
	name: 'product_goods_MaterialEditor'
})

const route = useRoute()
const router = useRouter()

const spuId = ref(0)
const goodsName = ref('')
const materials = ref<any[]>([])
const originalMaterials = ref<any[]>([]) // 存储原始数据用于对比
const loading = ref(false)
const saving = ref(false)
const showMaterialTypeModal = ref(false)
const materialTypeCallback = ref<((type: number) => void) | null>(null)

// 素材类型枚举 - 使用Enums.ts中的定义
const materialTypes = computed(() => {
	const typeDatas = Enums.goods.material.typeDatas
	return [
		{ value: typeDatas.TEXT[0], label: typeDatas.TEXT[1] },
		{ value: typeDatas.IMAGE[0], label: typeDatas.IMAGE[1] },
		{ value: typeDatas.VIDEO[0], label: typeDatas.VIDEO[1] }
	]
})

// 素材文本编辑器工具栏配置
const materialTextToolbar = {
	bold: true,
	italic: true,
	underline: true,
	strikethrough: true,
	fontSize: true,
	fontFamily: true,
	lineHeight: true,
	alignLeft: true,
	alignCenter: true,
	alignRight: true,
	link: false,
	image: false,
	table: false,
	undo: true,
	redo: true,
	customGroups: []
}

// 素材表格列配置
const materialColumns = computed(
	(): TableColumns => [
		{
			title: t('状态.排序'),
			dataIndex: 'material_sort',
			align: 'center' as const,
			key: 'material_sort',
			width: 80
		},
		{
			title: t('素材编辑.素材类型'),
			dataIndex: 'material_type',
			align: 'center' as const,
			key: 'material_type',
			width: 160
		},
		{
			title: t('素材编辑.素材内容'),
			dataIndex: 'material_text',
			align: 'center' as const,
			key: 'material_text',
			ellipsis: true
		},
		{
			title: t('状态.操作'),
			key: 'action',
			dataIndex: 'action',
			align: 'center' as const,
			width: 250
		}
	]
)

// 获取素材类型描述
const getMaterialTypeDesc = (type: number) => {
	const typeDatas = Enums.goods.material.typeDatas
	switch (type) {
		case typeDatas.TEXT[0]:
			return typeDatas.TEXT[1]
		case typeDatas.IMAGE[0]:
			return typeDatas.IMAGE[1]
		case typeDatas.VIDEO[0]:
			return typeDatas.VIDEO[1]
		default:
			return t('素材编辑.未知类型')
	}
}

// 获取商品信息和素材列表
const fetchGoodsMaterials = () => {
	spuId.value = Number(route.query.id) || 0
	if (spuId.value > 0) {
		loading.value = true
		const formParams = {
			spuId: spuId.value
		}
		Api.post('/product/materials/list', formParams, true)
			.then((res: any) => {
				// 设置商品名称
				goodsName.value = res.spu?.name || ''
				materials.value = res.list || []
				// 为每个素材添加类型描述
				materials.value.forEach((material: any) => {
					material._material_type = getMaterialTypeDesc(material.material_type)
				})
				// 保存原始数据用于对比
				originalMaterials.value = JSON.parse(JSON.stringify(materials.value))
				loading.value = false
			})
			.catch(() => {
				loading.value = false
			})
	}
}

// 更新所有素材的排序值
const updateMaterialSorts = () => {
	const validMaterials = materials.value.filter(material => !material._deleted)
	validMaterials.forEach((material, index) => {
		material.material_sort = index + 1
		// 不再手动设置isUpdated，在保存时通过对比判断
	})
}

// 弹框选择素材类型
const openMaterialTypeModal = (callback: (type: number) => void) => {
	materialTypeCallback.value = callback
	showMaterialTypeModal.value = true
}

// 处理素材类型选择
const handleMaterialTypeSelect = (type: number) => {
	if (materialTypeCallback.value) {
		materialTypeCallback.value(type)
		materialTypeCallback.value = null
	}
}

// 添加新素材
const handleAddMaterial = () => {
	openMaterialTypeModal((type: number) => {
		const newMaterial = {
			id: 0,
			material_type: type,
			material_text: '',
			material_file_id: 0,
			material_sort: 0, // 初始为0，会在updateMaterialSorts中更新
			isUpdated: true,
			isNew: true
		}
		materials.value.push(newMaterial)
		updateMaterialSorts()
		message.success(t('素材编辑.已添加新素材'))
	})
}

// 删除素材
const handleDeleteMaterial = (material: any, index: number) => {
	if (material.id) {
		// 已存在的素材，标记为删除
		material._deleted = true
	} else {
		// 新添加的素材，直接移除
		materials.value.splice(index, 1)
	}
	updateMaterialSorts()
	message.success(t('素材编辑.素材已删除'))
}

// 恢复删除的素材
const handleRestoreMaterial = (material: any) => {
	delete material._deleted
	updateMaterialSorts()
}

// 上移素材
const handleMoveUp = (index: number) => {
	if (index <= 0) {
		message.warning(t('素材编辑.已经是第一个素材，无法上移'))
		return
	}

	const validMaterials = materials.value.filter(material => !material._deleted)
	const currentIndex = validMaterials.findIndex(m => m === materials.value[index])

	if (currentIndex > 0) {
		// 交换位置
		const temp = materials.value[index]
		materials.value[index] = materials.value[index - 1]
		materials.value[index - 1] = temp

		// 更新排序值
		updateMaterialSorts()
	}
}

// 下移素材
const handleMoveDown = (index: number) => {
	const validMaterials = materials.value.filter(material => !material._deleted)
	const currentIndex = validMaterials.findIndex(m => m === materials.value[index])

	if (currentIndex < validMaterials.length - 1) {
		// 交换位置
		const temp = materials.value[index]
		materials.value[index] = materials.value[index + 1]
		materials.value[index + 1] = temp

		// 更新排序值
		updateMaterialSorts()
	} else {
		message.warning(t('素材编辑.已经是最后一个素材，无法下移'))
	}
}

// 插入素材
const handleInsertMaterial = (index: number) => {
	openMaterialTypeModal((type: number) => {
		const newMaterial = {
			id: 0,
			material_type: type,
			material_text: '',
			material_file_id: 0,
			material_sort: 0, // 初始为0，会在updateMaterialSorts中更新
			isUpdated: true,
			isNew: true
		}

		// 在指定位置插入新素材
		materials.value.splice(index + 1, 0, newMaterial)

		// 更新排序值
		updateMaterialSorts()

		message.success(t('素材编辑.已插入新素材'))
	})
}

// 文件上传处理（合并后的方法）
const handleFileUpload = async (fileInfo: any, material: any): Promise<boolean> => {
	try {
		// 如果是图片或视频类型，需要上传到服务器
		if (
			material.material_type === Enums.goods.material.typeDatas.IMAGE[0] ||
			material.material_type === Enums.goods.material.typeDatas.VIDEO[0]
		) {
			const base64Data = await Tool.blobToBase64(fileInfo)
			const formParams = { base64: base64Data }

			await Api.post('/other/file/upload-by-base64', formParams, true)
				.then((res: any) => {
					if (res && res.file.abUrl) {
						material.material_text = res.file.abUrl
						material.material_file_id = res.file.id || 0
						material.isUpdated = true
						const typeName =
							material.material_type === Enums.goods.material.typeDatas.IMAGE[0]
								? t('素材编辑.图片')
								: t('素材编辑.视频')
						message.success(
							typeName === t('素材编辑.图片')
								? t('素材编辑.图片上传成功')
								: t('素材编辑.视频上传成功')
						)
					}
				})
				.catch(() => {
					const typeName =
						material.material_type === Enums.goods.material.typeDatas.IMAGE[0]
							? t('素材编辑.图片')
							: t('素材编辑.视频')
					message.error(
						typeName === t('素材编辑.图片')
							? t('素材编辑.图片上传失败')
							: t('素材编辑.视频上传失败')
					)
				})
		}
	} catch (error) {
		console.error('文件上传失败:', error)
		message.error(t('素材编辑.文件上传失败'))
	}

	// 返回 false 阻止默认上传行为
	return false
}

// 检查素材是否被修改
const checkMaterialUpdated = (material: any): boolean => {
	// 如果是新素材，直接返回true
	if (material.isNew) {
		return true
	}

	// 查找对应的原始素材
	const originalMaterial = originalMaterials.value.find(om => om.id === material.id)
	if (!originalMaterial) {
		return true // 找不到原始数据，认为已修改
	}

	// 对比关键字段是否发生变化
	return (
		material.material_type !== originalMaterial.material_type ||
		material.material_text !== originalMaterial.material_text ||
		material.material_sort !== originalMaterial.material_sort ||
		material.material_file_id !== originalMaterial.material_file_id
	)
}

// 检查是否需要上传文件
const needsUpload = (material: any): boolean => {
	// 如果是图片类型且内容是 blob URL，需要上传
	if (
		material.material_type === Enums.goods.material.typeDatas.IMAGE[0] &&
		material.material_text?.startsWith('blob:')
	) {
		return true
	}
	// 如果是视频类型且内容是 blob URL，需要上传
	if (
		material.material_type === Enums.goods.material.typeDatas.VIDEO[0] &&
		material.material_text?.startsWith('blob:')
	) {
		return true
	}
	return false
}

// 保存素材 - 先上传图片和视频，再保存
const handleSaveMaterials = async () => {
	if (!spuId.value) {
		message.error(t('素材编辑.商品ID不存在'))
		return
	}

	// 过滤出有效的素材（未删除的）
	const validMaterials = materials.value.filter(material => !material._deleted)

	// 验证素材数据
	for (const material of validMaterials) {
		if (!material.material_type) {
			message.error(t('素材编辑.请选择素材类型'))
			return
		}
		if (!material.material_text?.trim()) {
			message.error(t('素材编辑.请输入素材内容'))
			return
		}
		if (!material.material_sort || material.material_sort < 0) {
			message.error(t('素材编辑.请输入有效的排序值'))
			return
		}
	}

	saving.value = true

	try {
		// 先上传所有需要上传的文件
		for (const material of validMaterials) {
			if (needsUpload(material)) {
				let loadingMessage: any = null
				try {
					loadingMessage = message.loading(t('素材编辑.正在上传文件...'), 0)
					// 使用合并后的文件上传方法
					await handleFileUpload(material.material_text, material)
					if (loadingMessage) {
						loadingMessage()
					}
				} catch (error) {
					if (loadingMessage) {
						loadingMessage()
					}
					message.error(t('素材编辑.文件上传失败，请重试'))
					saving.value = false
					return
				}
			}
		}

		// 根据PHP逻辑构建请求数据，使用新的isUpdated判断方式
		const listForm = validMaterials.map(material => ({
			id: material.id || 0,
			material_type: material.material_type,
			material_text: material.material_text,
			material_file_id: material.material_file_id || 0,
			material_sort: material.material_sort,
			isUpdated: checkMaterialUpdated(material)
		}))

		const formParams = {
			spuId: spuId.value,
			listForm: JSON.stringify(listForm)
		}

		await Api.post('/product/materials/edit', formParams, true)
		message.success(t('通知.保存成功'))
		fetchGoodsMaterials() // 重新加载数据
	} catch (error) {
		console.error('保存失败:', error)
		message.error(t('素材编辑.保存失败，请重试'))
	} finally {
		saving.value = false
	}
}

// 素材文本改变处理
const handleMaterialTextChange = (value: string, material: any) => {
	material.material_text = value
	// 不再手动设置isUpdated，在保存时通过对比判断
}

// 素材排序改变处理
const handleMaterialSortChange = (value: number | string | null, material: any) => {
	material.material_sort = Number(value) || 0
	// 不再手动设置isUpdated，在保存时通过对比判断
}

// 预览素材内容
const handlePreviewMaterial = (material: any) => {
	const typeDatas = Enums.goods.material.typeDatas

	if (material.material_type === typeDatas.IMAGE[0]) {
		// 图片预览
		Modal.info({
			title: '图片预览',
			width: 800,
			content: h('div', { class: 'flex justify-center' }, [
				h('img', {
					src: material.material_text,
					alt: '素材图片',
					class: 'max-w-full max-h-96 object-contain',
					onError: (e: any) => {
						e.target.style.display = 'none'
						if (e.target.nextElementSibling) {
							e.target.nextElementSibling.style.display = 'block'
						}
					}
				}),
				h(
					'div',
					{
						style: {
							display: 'none',
							textAlign: 'center',
							padding: '20px',
							color: '#999'
						}
					},
					'图片加载失败'
				)
			]),
			okText: '关闭'
		})
	} else if (material.material_type === typeDatas.VIDEO[0]) {
		// 视频预览
		Modal.info({
			title: '视频预览',
			width: 800,
			content: h('div', { class: 'flex justify-center' }, [
				h(
					'video',
					{
						src: material.material_text,
						controls: true,
						class: 'max-w-full max-h-96',
						onError: (e: any) => {
							e.target.style.display = 'none'
							if (e.target.nextElementSibling) {
								e.target.nextElementSibling.style.display = 'block'
							}
						}
					},
					'您的浏览器不支持视频播放'
				),
				h(
					'div',
					{
						style: {
							display: 'none',
							textAlign: 'center',
							padding: '20px',
							color: '#999'
						}
					},
					'视频加载失败'
				)
			]),
			okText: '关闭'
		})
	}
}

onMounted(() => {
	fetchGoodsMaterials()
})
</script>

<template>
	<IsGuest>
		<div class="p-4">
			<!-- 页面标题和商品信息 -->
			<div class="mb-6">
				<h2 class="text-xl font-bold mb-2">{{ t('素材编辑.商品素材管理') }}</h2>
				<p class="text-gray-600" v-if="spuId">
					{{ t('素材编辑.商品名称') }}: {{ goodsName || `商品ID: ${spuId}` }}
				</p>
			</div>

			<!-- 素材列表表格 -->
			<a-table
				:columns="materialColumns"
				:data-source="materials.filter(m => !m._deleted)"
				:loading="loading"
				:bordered="true"
				:pagination="false"
				row-key="id">
				<template #bodyCell="{ text, record, index, column }">
					<template v-if="column.key === 'material_type'">
						<span>
							{{ record._material_type || getMaterialTypeDesc(record.material_type) }}
						</span>
					</template>

					<template v-if="column.key === 'material_text'">
						<!-- 文本类型：显示富文本编辑器 -->
						<template
							v-if="record.material_type === Enums.goods.material.typeDatas.TEXT[0]">
							<RichTextEditor
								v-model="record.material_text"
								:toolbar="materialTextToolbar"
								:height="'90px'"
								:compact="true"
								:placeholder="t('素材编辑.请输入文本内容')"
								@change="value => handleMaterialTextChange(value, record)" />
						</template>

						<!-- 图片类型：使用AddCover组件 -->
						<template
							v-else-if="
								record.material_type === Enums.goods.material.typeDatas.IMAGE[0]
							">
							<div class="flex justify-center">
								<AddCover
									v-model:modelValue="record.material_text"
									@update:modelValue="
										value => handleMaterialTextChange(value, record)
									" />
							</div>
						</template>

						<!-- 视频类型：使用AddVideo组件 -->
						<template
							v-else-if="
								record.material_type === Enums.goods.material.typeDatas.VIDEO[0]
							">
							<div class="flex justify-center">
								<AddVideo
									v-model:modelValue="record.material_text"
									@update:modelValue="
										value => handleMaterialTextChange(value, record)
									" />
							</div>
						</template>

						<!-- 默认情况 -->
						<template v-else>
							<a-input
								v-model:value="record.material_text"
								@change="e => handleMaterialTextChange(e.target.value, record)"
								:placeholder="t('素材编辑.请输入素材内容')" />
						</template>
					</template>

					<template v-if="column.key === 'material_sort'">
						<span>{{ record.material_sort }}</span>
					</template>

					<template v-if="column.key === 'action'">
						<div class="flex justify-center gap-2">
							<a-button
								size="small"
								@click="handleMoveUp(index)"
								:disabled="index <= 0"
								v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
								{{ t('操作.上移') }}
							</a-button>
							<a-button
								size="small"
								@click="handleMoveDown(index)"
								:disabled="index >= materials.filter(m => !m._deleted).length - 1"
								v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
								{{ t('操作.下移') }}
							</a-button>
							<a-button
								size="small"
								type="primary"
								@click="handleInsertMaterial(index)"
								:disabled="index >= materials.filter(m => !m._deleted).length - 1"
								v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
								{{ t('操作.插入') }}
							</a-button>
							<a-button
								size="small"
								danger
								@click="handleDeleteMaterial(record, index)"
								v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
								{{ t('操作.删除') }}
							</a-button>
						</div>
					</template>
				</template>
			</a-table>

			<!-- 添加素材按钮 -->
			<div class="mb-4">
				<a-button
					type="primary"
					@click="handleAddMaterial"
					v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
					{{ t('素材编辑.添加素材') }}
				</a-button>
			</div>

			<!-- 已删除的素材 -->
			<div v-if="materials.filter(m => m._deleted).length > 0" class="mt-4">
				<h3 class="text-lg font-semibold mb-2 text-red-600">
					{{ t('素材编辑.已删除的素材') }}
				</h3>
				<div class="bg-red-50 border border-red-200 rounded p-3">
					<div
						v-for="(material, index) in materials.filter(m => m._deleted)"
						:key="material.id || `deleted-${index}`"
						class="flex justify-between items-center py-2 border-b border-red-100 last:border-b-0">
						<div class="flex items-center gap-3">
							<span class="font-medium">
								{{ getMaterialTypeDesc(material.material_type) }}
							</span>

							<!-- 文本素材：格式化HTML展示 -->
							<div
								v-if="
									material.material_type ===
									Enums.goods.material.typeDatas.TEXT[0]
								"
								class="max-w-md max-h-20 overflow-auto border border-gray-200 rounded p-2 bg-white">
								<div v-html="material.material_text" class="text-sm"></div>
							</div>

							<!-- 非文本素材：只展示预览按钮 -->
							<div v-else class="flex items-center gap-2">
								<!-- 图片预览按钮 -->
								<a-button
									v-if="
										material.material_type ===
											Enums.goods.material.typeDatas.IMAGE[0] &&
										material.material_text
									"
									size="small"
									type="link"
									@click="() => handlePreviewMaterial(material)">
									{{ t('素材编辑.预览图片') }}
								</a-button>

								<!-- 视频预览按钮 -->
								<a-button
									v-if="
										material.material_type ===
											Enums.goods.material.typeDatas.VIDEO[0] &&
										material.material_text
									"
									size="small"
									type="link"
									@click="() => handlePreviewMaterial(material)">
									{{ t('素材编辑.预览视频') }}
								</a-button>

								<!-- 无内容提示 -->
								<span v-if="!material.material_text" class="text-gray-400 text-sm">
									{{ t('素材编辑.无内容') }}
								</span>
							</div>
						</div>
						<a-button size="small" @click="handleRestoreMaterial(material)">
							{{ t('素材编辑.恢复') }}
						</a-button>
					</div>
				</div>
			</div>

			<!-- 空状态 -->
			<div v-if="materials.length === 0 && !loading" class="text-center py-8 text-gray-500">
				{{ t('素材编辑.暂无素材') }}
			</div>

			<!-- 素材类型选择弹框 -->
			<MaterialTypeSelectModal
				v-model:open="showMaterialTypeModal"
				@select="handleMaterialTypeSelect" />
		</div>

		<footer-toolbar>
			<div class="flex gap-2">
				<a-button @click="router.push({ path: '/product/goods/list' })">
					{{ t('素材编辑.商品列表') }}
				</a-button>
				<a-button
					v-if="spuId"
					@click="router.push({ path: '/product/goods/info', query: { id: spuId } })">
					{{ t('素材编辑.商品详情') }}
				</a-button>
				<a-button
					v-if="spuId && Api.hasPermission('商品库-商品管理-修改商品')"
					@click="router.push({ path: '/product/goods/edit', query: { id: spuId } })">
					{{ t('素材编辑.编辑商品') }}
				</a-button>
			</div>
			<div class="flex gap-2">
				<a-button
					type="primary"
					:loading="saving"
					@click="handleSaveMaterials"
					v-if="Api.hasPermission('商品库-商品管理-素材编辑')">
					{{ t('操作.保存') }}
				</a-button>
			</div>
		</footer-toolbar>
	</IsGuest>
</template>

<style lang="scss" scoped></style>
